From: Ray Strode Date: Tue, 6 Sep 2011 13:05:40 +0000 (-0400) Subject: gdm: add a power button X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~7680 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=a94a62764d6f9560735ae15f5a984c9311e0f4cd;p=gnome-shell.git gdm: add a power button Making users have to log in to power off the machine isn't a good idea. This commit adds a power menu similar to the one in the fallback greeter which offers 3 items: - Suspend - Restart - Power off https://bugzilla.gnome.org/show_bug.cgi?id=657822 --- diff --git a/js/Makefile.am b/js/Makefile.am index 0351f82d0..8924c34f9 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -3,7 +3,9 @@ jsdir = $(pkgdatadir)/js nobase_dist_js_DATA = \ gdm/batch.js \ + gdm/consoleKit.js \ gdm/loginDialog.js \ + gdm/powerMenu.js \ misc/config.js \ misc/docInfo.js \ misc/fileUtils.js \ diff --git a/js/gdm/consoleKit.js b/js/gdm/consoleKit.js new file mode 100644 index 000000000..d5eeb8986 --- /dev/null +++ b/js/gdm/consoleKit.js @@ -0,0 +1,32 @@ +// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- + +const DBus = imports.dbus; + +const ConsoleKitManagerIface = { + name: 'org.freedesktop.ConsoleKit.Manager', + methods: [{ name: 'CanRestart', + inSignature: '', + outSignature: 'b' }, + { name: 'CanStop', + inSignature: '', + outSignature: 'b' }, + { name: 'Restart', + inSignature: '', + outSignature: '' }, + { name: 'Stop', + inSignature: '', + outSignature: '' }] +}; + +function ConsoleKitManager() { + this._init(); +}; + +ConsoleKitManager.prototype = { + _init: function() { + DBus.system.proxifyObject(this, + 'org.freedesktop.ConsoleKit', + '/org/freedesktop/ConsoleKit/Manager'); + } +}; +DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface); diff --git a/js/gdm/powerMenu.js b/js/gdm/powerMenu.js new file mode 100644 index 000000000..10e832eb5 --- /dev/null +++ b/js/gdm/powerMenu.js @@ -0,0 +1,146 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- + * + * Copyright 2011 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +const Lang = imports.lang; +const UPowerGlib = imports.gi.UPowerGlib; + +const ConsoleKit = imports.gdm.consoleKit; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; + +function PowerMenuButton() { + this._init(); +} + +PowerMenuButton.prototype = { + __proto__: PanelMenu.SystemStatusButton.prototype, + + _init: function() { + PanelMenu.SystemStatusButton.prototype._init.call(this, 'system-shutdown', null); + this._consoleKitManager = new ConsoleKit.ConsoleKitManager(); + this._upClient = new UPowerGlib.Client(); + + this._createSubMenu(); + + this._upClient.connect('notify::can-suspend', + Lang.bind(this, this._updateHaveSuspend)); + this._updateHaveSuspend(); + + // ConsoleKit doesn't send notifications when shutdown/reboot + // are disabled, so we update the menu item each time the menu opens + this.menu.connect('open-state-changed', Lang.bind(this, + function(menu, open) { + if (open) { + this._updateHaveShutdown(); + this._updateHaveRestart(); + } + })); + this._updateHaveShutdown(); + this._updateHaveRestart(); + }, + + _updateVisibility: function() { + if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart) + this.actor.hide(); + else + this.actor.show(); + }, + + _updateHaveShutdown: function() { + this._consoleKitManager.CanStopRemote(Lang.bind(this, + function(result, error) { + if (!error) + this._haveShutdown = result; + else + this._haveShutdown = false; + + if (this._haveShutdown) { + this._powerOffItem.actor.show(); + } else { + this._powerOffItem.actor.hide(); + } + + this._updateVisibility(); + })); + }, + + _updateHaveRestart: function() { + this._consoleKitManager.CanRestartRemote(Lang.bind(this, + function(result, error) { + if (!error) + this._haveRestart = result; + else + this._haveRestart = false; + + if (this._haveRestart) { + this._restartItem.actor.show(); + } else { + this._restartItem.actor.hide(); + } + + this._updateVisibility(); + })); + }, + + _updateHaveSuspend: function() { + this._haveSuspend = this._upClient.get_can_suspend(); + + if (this._haveSuspend) + this._suspendItem.actor.show(); + else + this._suspendItem.actor.hide(); + + this._updateVisibility(); + }, + + _createSubMenu: function() { + let item; + + item = new PopupMenu.PopupMenuItem(_("Suspend")); + item.connect('activate', Lang.bind(this, this._onActivateSuspend)); + this.menu.addMenuItem(item); + this._suspendItem = item; + + item = new PopupMenu.PopupMenuItem(_("Restart")); + item.connect('activate', Lang.bind(this, this._onActivateRestart)); + this.menu.addMenuItem(item); + this._restartItem = item; + + item = new PopupMenu.PopupMenuItem(_("Power Off")); + item.connect('activate', Lang.bind(this, this._onActivatePowerOff)); + this.menu.addMenuItem(item); + this._powerOffItem = item; + }, + + _onActivateSuspend: function() { + if (this._haveSuspend) + this._upClient.suspend_sync(null); + }, + + _onActivateRestart: function() { + if (this._haveRestart) + this._consoleKitManager.RestartRemote(); + }, + + _onActivatePowerOff: function() { + if (this._haveShutdown) + this._consoleKitManager.StopRemote(); + } +}; diff --git a/js/ui/panel.js b/js/ui/panel.js index 1d2dc0f38..3976025bb 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -45,12 +45,13 @@ try { log('NMApplet is not supported. It is possible that your NetworkManager version is too old'); } -const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery']; +const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu']; const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = { 'a11y': imports.ui.status.accessibility.ATIndicator, 'volume': imports.ui.status.volume.Indicator, 'battery': imports.ui.status.power.Indicator, - 'keyboard': imports.ui.status.keyboard.XKBIndicator + 'keyboard': imports.ui.status.keyboard.XKBIndicator, + 'powerMenu': imports.gdm.powerMenu.PowerMenuButton }; // To make sure the panel corners blend nicely with the panel,